﻿using CCSSolderUI.Common.Event;
using CCSSolderUI.Models;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CCSSolderUI.ViewModels.Dialogs
{
    public class AxisDialogViewModel : BindableBase, IDialogAware
    {
        #region 变量
        AxisParm axisParm = default;
        Param param;
        SystemParam systemParam;
        IEventAggregator _eventAggregator;
        string partNumber = "";
        bool StopFlag = false;
        CancellationTokenSource source;
        #endregion
        #region 属性
        private bool servoState;
        public bool ServoState
        {
            get { return servoState; }
            set { SetProperty(ref servoState, value); }
        }
        private bool zeroState;
        public bool ZeroState
        {
            get { return zeroState; }
            set { SetProperty(ref zeroState, value); }
        }
        private bool alarmState;
        public bool AlarmState
        {
            get { return alarmState; }
            set { SetProperty(ref alarmState, value); }
        }
        private bool runningState;
        public bool RunningState
        {
            get { return runningState; }
            set { SetProperty(ref runningState, value); }
        }
        private bool pLimitState;
        public bool PLimitState
        {
            get { return pLimitState; }
            set { SetProperty(ref pLimitState, value); }
        }
        private bool nLimitState;
        public bool NLimitState
        {
            get { return nLimitState; }
            set { SetProperty(ref nLimitState, value); }
        }
        private double x1JogSpeed;
        public double X1JogSpeed
        {
            get { return x1JogSpeed; }
            set { SetProperty(ref x1JogSpeed, value); }
        }
        private double y1JogSpeed;
        public double Y1JogSpeed
        {
            get { return y1JogSpeed; }
            set { SetProperty(ref y1JogSpeed, value); }
        }
        private double z1JogSpeed;
        public double Z1JogSpeed
        {
            get { return z1JogSpeed; }
            set { SetProperty(ref z1JogSpeed, value); }
        }
        private double x1RunSpeed;
        public double X1RunSpeed
        {
            get { return x1RunSpeed; }
            set { SetProperty(ref x1RunSpeed, value); }
        }
        private double y1RunSpeed;
        public double Y1RunSpeed
        {
            get { return y1RunSpeed; }
            set { SetProperty(ref y1RunSpeed, value); }
        }
        private double z1RunSpeed;
        public double Z1RunSpeed
        {
            get { return z1RunSpeed; }
            set { SetProperty(ref z1RunSpeed, value); }
        }
        private double y1Abs;
        public double Y1Abs
        {
            get { return y1Abs; }
            set { SetProperty(ref y1Abs, value); }
        }
        private double z1Abs;
        public double Z1Abs
        {
            get { return z1Abs; }
            set { SetProperty(ref z1Abs, value); }
        }
        private double posX1;
        public double PosX1
        {
            get { return posX1; }
            set { SetProperty(ref posX1, value); }
        }
        private double encX1;
        public double EncX1
        {
            get { return encX1; }
            set { SetProperty(ref encX1, value); }
        }
        private double posY1;
        public double PosY1
        {
            get { return posY1; }
            set { SetProperty(ref posY1, value); }
        }
        private double encY1;
        public double EncY1
        {
            get { return encY1; }
            set { SetProperty(ref encY1, value); }
        }
        private double posZ1;
        public double PosZ1
        {
            get { return posZ1; }
            set { SetProperty(ref posZ1, value); }
        }
        private double encZ1;
        public double EncZ1
        {
            get { return encZ1; }
            set { SetProperty(ref encZ1, value); }
        }
        private ObservableCollection<bool> gTSDi = new ObservableCollection<bool>();
        public ObservableCollection<bool> GTSDi
        {
            get { return gTSDi; }
            set { SetProperty(ref gTSDi, value); }
        }
        private ObservableCollection<bool> gTSDo = new ObservableCollection<bool>();
        public ObservableCollection<bool> GTSDo
        {
            get { return gTSDo; }
            set { SetProperty(ref gTSDo, value); }
        }
        private AxisPoint initPoint;
        public AxisPoint InitPoint
        {
            get { return initPoint; }
            set { SetProperty(ref initPoint, value); }
        }
        private AxisPoint boardScanPoint1;
        public AxisPoint BoardScanPoint1
        {
            get { return boardScanPoint1; }
            set { SetProperty(ref boardScanPoint1, value); }
        }
        private AxisPoint boardScanPoint2;
        public AxisPoint BoardScanPoint2
        {
            get { return boardScanPoint2; }
            set { SetProperty(ref boardScanPoint2, value); }
        }
        private AxisPoint testPoint;
        public AxisPoint TestPoint
        {
            get { return testPoint; }
            set { SetProperty(ref testPoint, value); }
        }
        private bool isAxisBusy = false;
        public bool IsAxisBusy
        {
            get { return isAxisBusy; }
            set { SetProperty(ref isAxisBusy, value); }
        }
        private AxisPoint zSafePoint;
        public AxisPoint ZSafePoint
        {
            get { return zSafePoint; }
            set { SetProperty(ref zSafePoint, value); }
        }
        private AxisPoint zLaserPoint;
        public AxisPoint ZLaserPoint
        {
            get { return zLaserPoint; }
            set { SetProperty(ref zLaserPoint, value); }
        }
        private AxisPoint zLaserPoint2;
        public AxisPoint ZLaserPoint2
        {
            get { return zLaserPoint2; }
            set { SetProperty(ref zLaserPoint2, value); }
        }
        private double deltaZLimit;
        public double DeltaZLimit
        {
            get { return deltaZLimit; }
            set { SetProperty(ref deltaZLimit, value); }
        }
        private ObservableCollection<BarcodePointDisp> barPointList1 = new ObservableCollection<BarcodePointDisp>();
        public ObservableCollection<BarcodePointDisp> BarPointList1
        {
            get { return barPointList1; }
            set { SetProperty(ref barPointList1, value); }
        }
        private ObservableCollection<BarcodePointDisp> barPointList2 = new ObservableCollection<BarcodePointDisp>();
        public ObservableCollection<BarcodePointDisp> BarPointList2
        {
            get { return barPointList2; }
            set { SetProperty(ref barPointList2, value); }
        }
        #endregion
        #region 方法绑定
        private DelegateCommand<object> motionJogSelectionChangedEventCommand;
        public DelegateCommand<object> MotionJogSelectionChangedEventCommand =>
            motionJogSelectionChangedEventCommand ?? (motionJogSelectionChangedEventCommand = new DelegateCommand<object>(ExecuteMotionJogSelectionChangedEventCommand));
        private DelegateCommand<object> servoOnCommand;
        public DelegateCommand<object> ServoOnCommand =>
            servoOnCommand ?? (servoOnCommand = new DelegateCommand<object>(ExecuteServoOnCommand));
        private DelegateCommand<object> servoOffCommand;
        public DelegateCommand<object> ServoOffCommand =>
            servoOffCommand ?? (servoOffCommand = new DelegateCommand<object>(ExecuteServoOffCommand));
        private DelegateCommand<object> servoClrAlarmCommand;
        public DelegateCommand<object> ServoClrAlarmCommand =>
            servoClrAlarmCommand ?? (servoClrAlarmCommand = new DelegateCommand<object>(ExecuteServoClrAlarmCommand));
        private DelegateCommand<object> jogP_MouseDownCommand;
        public DelegateCommand<object> JogP_MouseDownCommand =>
            jogP_MouseDownCommand ?? (jogP_MouseDownCommand = new DelegateCommand<object>(ExecuteJogP_MouseDownCommand));

        private DelegateCommand<object> jogN_MouseDownCommand;
        public DelegateCommand<object> JogN_MouseDownCommand =>
            jogN_MouseDownCommand ?? (jogN_MouseDownCommand = new DelegateCommand<object>(ExecuteJogN_MouseDownCommand));
        private DelegateCommand jog_MouseUpCommand;
        public DelegateCommand Jog_MouseUpCommand =>
            jog_MouseUpCommand ?? (jog_MouseUpCommand = new DelegateCommand(ExecuteJog_MouseUpCommand));
        private DelegateCommand<object> getAbsCommand;
        public DelegateCommand<object> GetAbsCommand =>
            getAbsCommand ?? (getAbsCommand = new DelegateCommand<object>(ExecuteGetAbsCommand));
        private DelegateCommand saveButtonCommand;
        public DelegateCommand SaveButtonCommand =>
            saveButtonCommand ?? (saveButtonCommand = new DelegateCommand(ExecuteSaveButtonCommand));
        private DelegateCommand<object> outActionCommand;
        public DelegateCommand<object> OutActionCommand =>
            outActionCommand ?? (outActionCommand = new DelegateCommand<object>(ExecuteOutActionCommand));
        private DelegateCommand<object> getPositionCommand;
        public DelegateCommand<object> GetPositionCommand =>
            getPositionCommand ?? (getPositionCommand = new DelegateCommand<object>(ExecuteGetPositionCommand));
        private DelegateCommand<object> goPositionCommand;
        public DelegateCommand<object> GoPositionCommand =>
            goPositionCommand ?? (goPositionCommand = new DelegateCommand<object>(ExecuteGoPositionCommand));
        private DelegateCommand<object> jumpPositionCommand;
        public DelegateCommand<object> JumpPositionCommand =>
            jumpPositionCommand ?? (jumpPositionCommand = new DelegateCommand<object>(ExecuteJumpPositionCommand));
        private DelegateCommand<object> barPointListRowEditEndingCommand;
        public DelegateCommand<object> BarPointListRowEditEndingCommand =>
            barPointListRowEditEndingCommand ?? (barPointListRowEditEndingCommand = new DelegateCommand<object>(ExecuteBarPointListRowEditEndingCommand));
        private DelegateCommand<object> barPointListTeachPosCommand;
        public DelegateCommand<object> BarPointListTeachPosCommand =>
            barPointListTeachPosCommand ?? (barPointListTeachPosCommand = new DelegateCommand<object>(ExecuteBarPointListTeachPosCommand));
        private DelegateCommand<object> barPointListJumpPosCommand;
        public DelegateCommand<object> BarPointListJumpPosCommand =>
            barPointListJumpPosCommand ?? (barPointListJumpPosCommand = new DelegateCommand<object>(ExecuteBarPointListJumpPosCommand));
        private DelegateCommand<object> barPointListGoPosCommand;
        public DelegateCommand<object> BarPointListGoPosCommand =>
            barPointListGoPosCommand ?? (barPointListGoPosCommand = new DelegateCommand<object>(ExecuteBarPointListGoPosCommand));

        async void ExecuteBarPointListGoPosCommand(object obj)
        {
            source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            GTSCard.Instance.ServoOn(GTSCard.Instance.X1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Y1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Z1);
            if (obj is BarcodePointDisp barpoint)
            {
                if (MessageBox.Show($"确认运动到\"{barpoint.Name}\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                {
                    IsAxisBusy = true;
                    var _point = new AxisPoint { 
                        X = barpoint.X,
                        Y = barpoint.Y,
                        Z = barpoint.Z
                    };
                    await Task.Run(() => GoActionXYZ(token, _point), token).ContinueWith(t => IsAxisBusy = false);
                }
            }
        }
        async void ExecuteBarPointListJumpPosCommand(object obj)
        {
            source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            GTSCard.Instance.ServoOn(GTSCard.Instance.X1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Y1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Z1);
            if (obj is BarcodePointDisp barpoint)
            {
                if (MessageBox.Show($"确认运动到\"{barpoint.Name}\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                {
                    IsAxisBusy = true;
                    var _point = new AxisPoint
                    {
                        X = barpoint.X,
                        Y = barpoint.Y,
                        Z = barpoint.Z
                    };
                    await Task.Run(() => JumpActionXYZ(token, _point), token).ContinueWith(t => IsAxisBusy = false);
                }
            }
        }
        void ExecuteBarPointListTeachPosCommand(object obj)
        {
            if (obj is BarcodePointDisp barpoint)
                if (MessageBox.Show($"确认设置\"{barpoint.Name}\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                {
                    using (var db = new DTContext(partNumber))
                    {
                        var point = db.BarcodePoints.FirstOrDefault(p => p.Id == barpoint.Id);
                        if (point != null)
                        {
                            barpoint.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                            barpoint.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                            barpoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                            db.SaveChanges();
                        }
                    }
                    _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                }
        }
        void ExecuteBarPointListRowEditEndingCommand(object obj)
        {
            if (obj is BarcodePointDisp barpoint)
            {
                try
                {
                    using var mdb = new DTContext(partNumber);
                    var point = mdb.BarcodePoints.FirstOrDefault(p => p.Id == barpoint.Id);
                    if (point != null)
                    {
                        point.X = barpoint.X;
                        point.Y = barpoint.Y;
                        point.Z = barpoint.Z;
                        mdb.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Print", Content = ex.Message });
                }
            }
        }
        async void ExecuteJumpPositionCommand(object obj)
        {
            source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            GTSCard.Instance.ServoOn(GTSCard.Instance.X1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Y1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Z1);
            switch (obj.ToString())
            {
                case "InitPoint":
                    if (MessageBox.Show($"确认运动到\"初始点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => JumpActionXYZ(token, InitPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "TestPoint":
                    if (MessageBox.Show($"确认运动到\"Test点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => JumpActionXYZ(token, TestPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "BoardScanPoint1":
                    if (MessageBox.Show($"确认运动到\"板1扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => JumpActionXYZ(token, BoardScanPoint1), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "BoardScanPoint2":
                    if (MessageBox.Show($"确认运动到\"板2扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => JumpActionXYZ(token, BoardScanPoint2), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                default:
                    break;
            }
        }
        async void ExecuteGoPositionCommand(object obj)
        {
            source = new CancellationTokenSource();
            CancellationToken token = source.Token;
            GTSCard.Instance.ServoOn(GTSCard.Instance.X1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Y1);
            GTSCard.Instance.ServoOn(GTSCard.Instance.Z1);
            switch (obj.ToString())
            {
                case "InitPoint":
                    if (MessageBox.Show($"确认运动到\"初始点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, InitPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "TestPoint":
                    if (MessageBox.Show($"确认运动到\"Test点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, TestPoint), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "BoardScanPoint1":
                    if (MessageBox.Show($"确认运动到\"板1扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, BoardScanPoint1), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "BoardScanPoint2":
                    if (MessageBox.Show($"确认运动到\"板2扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoActionXYZ(token, BoardScanPoint2), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "ZSafePoint":
                    if (MessageBox.Show($"确认运动到\"Z安全位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoAction(token, GTSCard.Instance.Z1, ZSafePoint.Z, Z1JogSpeed), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "ZLaserPoint":
                    if (MessageBox.Show($"确认运动到\"Z焊接①位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoAction(token, GTSCard.Instance.Z1, ZLaserPoint.Z, Z1JogSpeed), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                case "ZLaserPoint2":
                    if (MessageBox.Show($"确认运动到\"Z焊接②位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        IsAxisBusy = true;
                        await Task.Run(() => GoAction(token, GTSCard.Instance.Z1, ZLaserPoint2.Z, Z1JogSpeed), token).ContinueWith(t => IsAxisBusy = false);
                    }
                    break;
                default:
                    break;
            }
        }
        void ExecuteGetPositionCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "InitPoint":
                    if (MessageBox.Show($"确认设置\"初始点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "Init");
                            if (point != null)
                            {
                                InitPoint.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                                InitPoint.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                                InitPoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                case "TestPoint":
                    if (MessageBox.Show($"确认设置\"Test点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        TestPoint.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                        TestPoint.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                        TestPoint.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);                        
                    }
                    break;
                case "BoardScanPoint1":
                    if (MessageBox.Show($"确认设置\"板1扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "BoardScan1");
                            if (point != null)
                            {
                                BoardScanPoint1.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                                BoardScanPoint1.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                                BoardScanPoint1.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                case "BoardScanPoint2":
                    if (MessageBox.Show($"确认设置\"板2扫码点\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "BoardScan2");
                            if (point != null)
                            {
                                BoardScanPoint2.X = point.X = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                                BoardScanPoint2.Y = point.Y = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                                BoardScanPoint2.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                case "ZSafePoint":
                    if (MessageBox.Show($"确认设置\"Z安全位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZSafe");
                            if (point != null)
                            {
                                ZSafePoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                case "ZLaserPoint":
                    if (MessageBox.Show($"确认设置\"Z激光①位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser");
                            if (point != null)
                            {
                                ZLaserPoint.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                case "ZLaserPoint2":
                    if (MessageBox.Show($"确认设置\"Z激光②位\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        using (var db = new DTContext(partNumber))
                        {
                            var point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser2");
                            if (point != null)
                            {
                                ZLaserPoint2.Z = point.Z = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);
                                db.SaveChanges();
                            }
                        }
                        _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
                    }
                    break;
                default:
                    break;
            }
        }
        void ExecuteOutActionCommand(object obj)
        {
            if (GTSCard.Instance.OpenCardOk)
            {
                short bitno = short.Parse(obj.ToString());
                GTSCard.Instance.SetDo(bitno, (short)(GTSDo[bitno] ? 0 : 1));
            }
        }
        void ExecuteSaveButtonCommand()
        {
            param.X1JogSpeed = X1JogSpeed;
            param.Y1JogSpeed = Y1JogSpeed;
            param.Z1JogSpeed = Z1JogSpeed;
            param.X1RunSpeed = X1RunSpeed;
            param.Y1RunSpeed = Y1RunSpeed;
            param.Z1RunSpeed = Z1RunSpeed;
            param.DeltaZLimit = DeltaZLimit;
            try
            {
                string jsonString = JsonConvert.SerializeObject(param, Formatting.Indented);
                File.WriteAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, partNumber, "Param.json"), jsonString);
                MessageBox.Show("保存完成", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);

                using (var db = new DTContext(partNumber))
                {
                    var point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser");
                    if (point != null)
                    {
                        point.Z = ZLaserPoint.Z;
                        
                    }
                    var point2 = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser2");
                    if (point2 != null)
                    {
                        point2.Z = ZLaserPoint2.Z;
                    }
                    var point3 = db.XYZPoints.FirstOrDefault(p => p.Name == "ZSafe");
                    if (point3 != null)
                    {
                        point3.Z = InitPoint.Z;

                    }
                    if (point != null || point2 != null || point3 != null)
                    {
                        db.SaveChanges();
                    }
                }
                _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Update", Content = null });
            }
            catch (Exception ex)
            {
                _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Print", Content = ex.Message });
            }
        }
        void ExecuteGetAbsCommand(object obj)
        {
            if (MessageBox.Show($"确认重新设置绝对值原点吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                switch (obj.ToString())
                {
                    case "1":
                        Y1Abs = systemParam.Y1Abs = ServoModbus.Instance.ReadInovance(1) * GTSCard.Instance.Y1.Equiv;
                        GTSCard.Instance.SigAxisPosSet(GTSCard.Instance.Y1, 0);
                        GTSCard.Instance.SigAxisEncSet(GTSCard.Instance.Y1, 0);
                        break;
                    case "2":
                        Z1Abs = systemParam.Z1Abs = ServoModbus.Instance.ReadInovance(2) * GTSCard.Instance.Z1.Equiv;
                        GTSCard.Instance.SigAxisPosSet(GTSCard.Instance.Z1, 0);
                        GTSCard.Instance.SigAxisEncSet(GTSCard.Instance.Z1, 0);
                        break;
                    default:
                        break;
                }
                try
                {
                    string jsonString = JsonConvert.SerializeObject(systemParam, Formatting.Indented);
                    File.WriteAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SystemParam.json"), jsonString);
                    MessageBox.Show("零点设置完成", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog", Type = "Print", Content = ex.Message });
                }

            }

        }
        void ExecuteJog_MouseUpCommand()
        {
            GTSCard.Instance.AxisStop(GTSCard.Instance.X1, 1);
            GTSCard.Instance.AxisStop(GTSCard.Instance.Y1, 1);
            GTSCard.Instance.AxisStop(GTSCard.Instance.Z1, 1);
        }
        void ExecuteJogP_MouseDownCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.X1, 1, X1JogSpeed);
                    break;
                case "1":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.Y1, 1, Y1JogSpeed);
                    break;
                case "2":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.Z1, 1, Z1JogSpeed);
                    break;
                default:
                    break;
            }
        }

        void ExecuteJogN_MouseDownCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.X1, 0, X1JogSpeed);
                    break;
                case "1":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.Y1, 0, Y1JogSpeed);
                    break;
                case "2":
                    GTSCard.Instance.AxisJog(GTSCard.Instance.Z1, 0, Z1JogSpeed);
                    break;
                default:
                    break;
            }
        }

        void ExecuteServoClrAlarmCommand(object obj)
        {
            GTSCard.Instance.ClearAlm(axisParm);
        }
        void ExecuteServoOffCommand(object obj)
        {
            GTSCard.Instance.ServoOff(axisParm);
        }
        void ExecuteServoOnCommand(object obj)
        {
            GTSCard.Instance.ServoOn(axisParm);
            GTSCard.Instance.SigAxisPosSet(axisParm, GTSCard.Instance.GetEnc(axisParm));
        }
        void ExecuteMotionJogSelectionChangedEventCommand(object obj)
        {
            RefreshSts();
            GetAxis((int)obj);
        }
        #endregion
        #region 导航
        public string Title => "轴";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            StopFlag = true;
            if (source != null)
            {
                GTSCard.Instance.AxisStop(GTSCard.Instance.X1, 1);
                GTSCard.Instance.AxisStop(GTSCard.Instance.Y1, 1);
                GTSCard.Instance.AxisStop(GTSCard.Instance.Z1, 1);
                source.Cancel();
            }
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            partNumber = parameters.GetValue<string>("PartNumber");
            LoadParam();
            Update(partNumber);
            RefreshSts();
            GetAxis(0);
            UpdateUI();
        }
        #endregion
        #region 构造函数
        public AxisDialogViewModel(IEventAggregator ea)
        {
            _eventAggregator = ea;
            _eventAggregator.GetEvent<MessagePrintEvent>().Subscribe(MessageReceived);
            for (int i = 0; i < 16; i++)
            {
                GTSDi.Add(false);
            }
            for (int i = 0; i < 16; i++)
            {
                GTSDo.Add(false);
            }
            
        }

        #endregion
        #region 功能函数
        private void MessageReceived(Common.Event.Message obj)
        {
            switch (obj.Type)
            {
                case "Select":
                    partNumber = obj.Content;
                    LoadParam();
                    Update(partNumber);
                    break;
                case "Update":
                    if (obj.Sender != "AxisDialog")
                    {
                        LoadParam();
                        Update(partNumber);
                    }
                    break;
                case "DebugPosition":
                    if (obj.Sender == "CameraOperationDialog")
                    {
                        var strs = obj.Content.Split(new char[] { ','});
                        TestPoint.X = double.Parse(strs[0]);
                        TestPoint.Y = double.Parse(strs[1]);
                        TestPoint.Z = double.Parse(strs[2]);
                    }
                    break;
                case "Delete":
                    if (obj.Sender == "PartNumberDialog")
                    {
                        try
                        {
                            string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SystemParam.json"));
                            systemParam = JsonConvert.DeserializeObject<SystemParam>(jsonString);
                        }
                        catch { }
                    }
                    break;
                default:
                    break;
            }
        }
        private void RefreshSts()
        {
            ServoState = false;
            ZeroState = false;
            AlarmState = false;
            RunningState = false;
            PLimitState = false;
            NLimitState = false;
        }
        private void GetAxis(int AxisNo)
        {
            switch (AxisNo)
            {
                case 0:
                    axisParm = GTSCard.Instance.X1;
                    break;
                case 1:
                    axisParm = GTSCard.Instance.Y1;
                    break;
                case 2:
                    axisParm = GTSCard.Instance.Z1;
                    break;
                default:
                    break;
            }
        }
        void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "SystemParam.json"));
                systemParam = JsonConvert.DeserializeObject<SystemParam>(jsonString);
                //Json序列化，从文件读取
                jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, partNumber, "Param.json"));
                param = JsonConvert.DeserializeObject<Param>(jsonString);
            }
            catch (Exception ex)
            {
                _eventAggregator.GetEvent<MessagePrintEvent>().Publish(new Common.Event.Message() { Sender = "AxisDialog",Type = "Print",Content = ex.Message });
            }
        }
        void Update(string partnum)
        {
            using (var db = new DTContext(partnum))
            {
                var point = db.XYZPoints.FirstOrDefault(p => p.Name == "Init");
                if (point != null)
                {
                    InitPoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                    TestPoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "BoardScan1");
                if (point != null)
                {
                    BoardScanPoint1 = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "BoardScan2");
                if (point != null)
                {
                    BoardScanPoint2 = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZSafe");
                if (point != null)
                {
                    ZSafePoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser");
                if (point != null)
                {
                    ZLaserPoint = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }
                point = db.XYZPoints.FirstOrDefault(p => p.Name == "ZLaser2");
                if (point != null)
                {
                    ZLaserPoint2 = new AxisPoint
                    {
                        X = point.X,
                        Y = point.Y,
                        Z = point.Z
                    };
                }

                var barPoints = db.BarcodePoints.Where(barp => barp.Hand == 0).OrderBy(barp => barp.PcsOrder);
                if (barPoints.Any())
                {
                    barPoints.ToList().ForEach(barp => {
                        BarPointList1.Add(new BarcodePointDisp { 
                            Id = barp.Id,
                            PcsOrder = barp.PcsOrder,
                            X = barp.X,
                            Y = barp.Y,
                            Z = barp.Z,
                            Name = barp.Name,                            
                        });
                    });
                }
                barPoints = db.BarcodePoints.Where(barp => barp.Hand == 1).OrderBy(barp => barp.PcsOrder);
                if (barPoints.Any())
                {
                    barPoints.ToList().ForEach(barp => {
                        BarPointList2.Add(new BarcodePointDisp
                        {
                            Id = barp.Id,
                            PcsOrder = barp.PcsOrder,
                            X = barp.X,
                            Y = barp.Y,
                            Z = barp.Z,
                            Name = barp.Name,
                        });
                    });
                }
            }
            Y1Abs = systemParam.Y1Abs;
            Z1Abs = systemParam.Z1Abs;
            X1JogSpeed = param.X1JogSpeed;
            Y1JogSpeed = param.Y1JogSpeed;
            Z1JogSpeed = param.Z1JogSpeed;
            X1RunSpeed = param.X1RunSpeed;
            Y1RunSpeed = param.Y1RunSpeed;
            Z1RunSpeed = param.Z1RunSpeed;
            DeltaZLimit = param.DeltaZLimit;
        }
        private async void UpdateUI()
        {
            while (!StopFlag)
            {
                try
                {
                    if (GTSCard.Instance.OpenCardOk)
                    {
                        //IO
                        int diPort1 = GTSCard.Instance.GetDiPort1();
                        int doPort1 = GTSCard.Instance.GetDoPort1();
                        for (int i = 0; i < 16; i++)
                        {
                            GTSDi[i] = (diPort1 & (1 << i)) == 0;
                            GTSDo[i] = (doPort1 & (1 << i)) == 0;
                        }
                        //轴状态
                        AxisStatus axisStatus = GTSCard.Instance.GetAxisStatus(axisParm);
                        ZeroState = axisStatus.FlagHome;
                        RunningState = !axisStatus.FlagMoveEnd;
                        ServoState = axisStatus.FlagServoOn;
                        PLimitState = axisStatus.FlagPosLimit;
                        NLimitState = axisStatus.FlagNeglimit;
                        AlarmState = axisStatus.FlagAlm;

                        PosX1 = Math.Round(GTSCard.Instance.GetPos(GTSCard.Instance.X1), 3);
                        EncX1 = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.X1), 3);
                        PosY1 = Math.Round(GTSCard.Instance.GetPos(GTSCard.Instance.Y1), 3);
                        EncY1 = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Y1), 3);
                        PosZ1 = Math.Round(GTSCard.Instance.GetPos(GTSCard.Instance.Z1), 3);
                        EncZ1 = Math.Round(GTSCard.Instance.GetEnc(GTSCard.Instance.Z1), 3);

                    }
                }
                catch { }
                await Task.Delay(200);
            }
        }
        private void GoAction(CancellationToken token, AxisParm axis, double Pos, double speed)
        {
            int stepnum = 0;
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        GTSCard.Instance.AxisPosMove(ref axis, Pos, speed);
                        stepnum = 1;
                        break;
                    case 1:
                        if (GTSCard.Instance.AxisCheckDone(axis))
                        {
                            return;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void GoActionXYZ(CancellationToken token, AxisPoint point)
        {
            int stepnum = 0;
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.X1, point.X, X1JogSpeed);
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Y1, point.Y, Y1JogSpeed);
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Z1, point.Z, Z1JogSpeed);
                        stepnum = 1;
                        break;
                    case 1:
                        if (GTSCard.Instance.AxisCheckDone(GTSCard.Instance.X1) && GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Y1) && GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Z1))
                        {
                            return;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        private void JumpActionXYZ(CancellationToken token, AxisPoint point)
        {
            int stepnum = 0;
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                switch (stepnum)
                {
                    case 0:
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Z1, ZSafePoint.Z, Z1JogSpeed);
                        stepnum = 1;
                        break;
                    case 1:
                        if (GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Z1))
                        {
                            stepnum = 2;
                        }
                        break;
                    case 2:
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.X1, point.X, X1JogSpeed);
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Y1, point.Y, Y1JogSpeed);
                        stepnum = 3;
                        break;
                    case 3:
                        if (GTSCard.Instance.AxisCheckDone(GTSCard.Instance.X1) && GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Y1))
                        {
                            stepnum = 4;
                        }
                        break;
                    case 4:
                        GTSCard.Instance.AxisPosMove(ref GTSCard.Instance.Z1, point.Z, X1JogSpeed);
                        stepnum = 5;
                        break;
                    case 5:
                        if (GTSCard.Instance.AxisCheckDone(GTSCard.Instance.Z1))
                        {
                            return;
                        }
                        break;
                    default:
                        break;
                }
                System.Threading.Thread.Sleep(100);
            }
        }
        #endregion
    }
    public class AxisPoint : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;

        private double x;
        public double X
        {
            get { return x; }
            set { x = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("X"));
                }
            }
        }
        private double y;
        public double Y
        {
            get { return y; }
            set
            {
                y = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Y"));
                }
            }
        }
        private double z;
        public double Z
        {
            get { return z; }
            set
            {
                z = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Z"));
                }
            }
        }
    }
    public class BarcodePointDisp : DispBase
    {
        public int Id { get; set; }
        public int PcsOrder { get; set; }

        private double x;

        public double X
        {
            get { return x; }
            set
            {
                if (x != value)
                {
                    x = value;
                    OnPropertyChanged();
                }
            }
        }

        private double y;

        public double Y
        {
            get { return y; }
            set
            {
                if (y != value)
                {
                    y = value;
                    OnPropertyChanged();
                }
            }
        }

        private double z;

        public double Z
        {
            get { return z; }
            set
            {
                if (z != value)
                {
                    z = value;
                    OnPropertyChanged();
                }
            }
        }
        public string Name { get; set; }
    }
}
